package com.skwyb.form.utils;

import com.skwyb.form.constants.ResultCode;
import com.skwyb.form.core.BusinessException;
import java.nio.charset.StandardCharsets;
import java.security.Security;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang3.StringUtils;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.springframework.util.Base64Utils;
import org.springframework.util.DigestUtils;

/**
 * 加解密方式
 */
@Log4j2
public class CryptUtil {

    private static String KEY;

    private static String IV;

    static {
        KEY = PropertiesUtils.getValue("crypt.key");
        IV = PropertiesUtils.getValue("crypt.iv");
    }

    public static byte[] encrypt(byte[] str) throws Exception {
        byte[] raw = KEY.getBytes(StandardCharsets.UTF_8);
        Security.addProvider(new BouncyCastleProvider());
        SecretKeySpec keySpec = new SecretKeySpec(raw, "AES");
        //"算法/模式/补码方式"
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");
        //使用CBC模式，需要一个向量iv，可增加加密算法的强度
        IvParameterSpec iv = new IvParameterSpec(IV.getBytes());
        cipher.init(Cipher.ENCRYPT_MODE, keySpec, iv);
        return Base64Utils.encode(cipher.doFinal(str));
    }

    public static byte[] decrypt(byte[] str) throws Exception {
        byte[] raw = KEY.getBytes(StandardCharsets.UTF_8);
        SecretKeySpec keySpec = new SecretKeySpec(raw, "AES");
        Security.addProvider(new BouncyCastleProvider());
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");
        IvParameterSpec iv = new IvParameterSpec(IV.getBytes());
        cipher.init(Cipher.DECRYPT_MODE, keySpec, iv);
        return cipher.doFinal(Base64Utils.decode(str));
    }

    public static String getAnonymousStr(String str) {
        if (StringUtils.isBlank(str)) {
            return "";
        }
        if (str.length() >= 11) {
            str = str.substring(0, 3) + "****" + str.substring(7);
        }
        return str;
    }

    public static String md5AesHex(String str) {
        try {
            return DigestUtils.md5DigestAsHex(encrypt(str.getBytes(StandardCharsets.UTF_8)));
        } catch (Exception e) {
            throw new BusinessException(ResultCode.FAIL);
        }
    }
}
